package com.gitee.lokiy.internal

import android.app.Activity
import android.content.Intent
import android.content.res.XmlResourceParser
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.lokiy.adapter.ViewBindingAdapter
import com.lokiy.core.activity.CommonActivity
import com.lokiy.core.fragment.BasicFragment
import com.lokiy.demo.databinding.FragmentBasicXmlBinding
import com.lokiy.demo.databinding.ItemDevToolsBinding

/**
 * @author Lokiy
 * @date 2022-07-17 上午10:07
 */
open class BasicXmlFragment : BasicFragment() {

    private lateinit var binding: FragmentBasicXmlBinding

    private val items = arrayListOf<ItemInfo>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = FragmentBasicXmlBinding.inflate(layoutInflater)
        return binding.root
    }

    @Suppress("UNCHECKED_CAST")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.toolbar.setNavigationOnClickListener {
            activity?.onBackPressed()
        }
        val parser = requireContext().resources.getXml(requireContext().resources.getIdentifier(getXmlName(), "xml", requireContext().packageName))
        var tagType: Int
        var itemInfo: ItemInfo? = null
        var intent: Intent? = null
        var currentTag = ""
        while (parser.next().also { tagType = it } != XmlResourceParser.END_DOCUMENT) {
            val name = parser.name ?: currentTag
            currentTag = name
            when (tagType) {
                XmlResourceParser.START_TAG -> {
                    when (name) {
                        "title" -> {
                        }
                        "item" -> itemInfo = ItemInfo(parser.getAttributeValue(null, "label"))
                        "intent" -> {
                            intent = Intent().also { it.setClassName(requireContext(), parser.getAttributeValue(null, "class")) }
                        }
                        "extra" -> {
                            intent?.let {
                                val key = parser.getAttributeValue(null, "key")
                                val type = parser.getAttributeValue(null, "type")
                                val value = parser.getAttributeValue(null, "value")
                                if (key != null && value != null && itemInfo != null) {
                                    when (type) {
                                        "string" -> it.putExtra(key, value)
                                        "float" -> it.putExtra(key, value.toFloatOrNull())
                                        "int" -> it.putExtra(key, value.toIntOrNull())
                                        "double" -> it.putExtra(key, value.toDouble())
                                        "long" -> it.putExtra(key, value.toLongOrNull())
                                        else -> Log.w("Dev", "Unsupported type: $type")
                                    }
                                }
                            }
                        }
                    }
                }
                XmlResourceParser.TEXT -> {
                    if (name == "title") {
                        binding.toolbar.title = parser.text
                    }
                }
                XmlResourceParser.END_TAG -> {
                    if (name == "item") {
                        itemInfo ?: continue
                        itemInfo.run {
                            clickListener = View.OnClickListener {
                                val itemIntent = this.intent
                                itemIntent ?: return@OnClickListener toast("item:${this.title} 没有定义 intent")
                                val clazz: Class<*> = runCatching {
                                    Class.forName(itemIntent.component?.className ?: return@OnClickListener)
                                }.getOrNull() ?: return@OnClickListener toast("找不到class${itemIntent.component?.className}")

                                if (Fragment::class.java.isAssignableFrom(clazz)) {
                                    CommonActivity.startActivity(requireContext(), clazz as Class<out Fragment?>?, itemIntent.extras)
                                } else if (Activity::class.java.isAssignableFrom(clazz)) {
                                    requireContext().startActivity(itemIntent)
                                }
                            }
                        }
                        items += itemInfo
                        itemInfo = null
                    } else if (name == "intent") {
                        itemInfo?.intent = intent
                        intent = null
                    }
                }
            }
        }
        parser.close()

        binding.recyclerView.adapter = ViewBindingAdapter<ItemInfo, ItemDevToolsBinding> { holder, item ->
            holder.binding.titleTv.text = item.title
            holder.binding.root.setOnClickListener(item.clickListener)
        }

    }

    private fun toast(text: String) {
        Toast.makeText(requireContext(), text, Toast.LENGTH_LONG).show()
    }

    private fun getXmlName(): String {
        val diff: Int = 'a' - 'A'
        return this::class.java.simpleName.replace("Fragment", "").map {
            if (it in 'A'..'Z') {
                "_" + (it + diff)
            } else {
                it + ""
            }
        }.joinToString("").substring(1)
    }
}


internal class ItemInfo(var title: String = "", var intent: Intent? = null, var clickListener: View.OnClickListener = View.OnClickListener { })